﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpSphinx.Linguist.Dictionary;
using SharpSphinx.Util;

namespace SharpSphinx.Result
{
    public class Node
    {

        private static int nodeCount;

        private String m_id;
        private Word m_word;
        private int beginTime = -1;
        private int endTime = -1;
        private List<Edge> enteringEdges = new List<Edge>();
        private List<Edge> leavingEdges = new List<Edge>();
        private double forwardScore;
        private double backwardScore;
        private double posterior;
        private Node bestPredecessor;
        private double ViterbiSocre;
        private ISet<Node> descendants; 


       protected Node(Word word, int beginTime, int endTime)
           : this(NextNodeId, word,beginTime,endTime)
        {
           
        }


       protected Node(String id, Word word, int beginTime, int endTime)
       {
           this.m_id = id;
           this.m_word = word;
           this.beginTime = beginTime;
           this.endTime = endTime;
           if (endTime != -1)
           {
               if (beginTime > endTime)
               {
                   throw new Exception("Begin time (" + beginTime + ") later than end Time (" + endTime + ')');
               }
           }

           this.forwardScore = LogMath.LogZero;
           this.backwardScore = LogMath.LogZero;
           this.posterior = LogMath.LogZero;
       }


       protected static String NextNodeId
       {
           get
           {
               return nodeCount.ToString();
           }
       }

       protected bool HasEdgeToNode(Node n)
       {
           return getEdgeToNode(n) != null;
       }

       
        public Edge getEdgeToNode(Node n)
        {
          
            foreach (Edge e in leavingEdges)
            {
                if (e.ToNode == n) { return e;}

            }

            return null;
            
        }

        public Edge getEdgeFromNode(Node n)
        {
            foreach (Edge e in enteringEdges)
            {
                if (e.FromNode == n)
                {
                    return e;
                }
            }

            return null;
        }

        protected bool HasEdgeFromNode(Node n)
        {
            return getEdgeFromNode(n) != null;
        }

    }   

}

